#pragma once
#include <map>

// Graphs
#include "_GraphData.h"

// Property dialogs
#include "_GraphPropertyDialog.h"
#include "NewMarkerDialog.h"

// Parts of the control
#include "_Border.h"
#include "_Title.h"
#include "_XAxis.h"
#include "_YAxis.h"
#include "_GraphArea.h"
#include "_GraphLayout.h"
#include "_SelectionMarkerX.h"
#include "_XMarker.h"
#include "_YMarker.h"

using namespace std;


/////////////////////////////////////////////////////////////////////////////
// _GraphControl window

class _GraphControl : public CWnd {

    public:
        // Constructor
        _GraphControl();

        map<int, _GraphData>* getGraphs() {
            return &m_GraphData;
        }

    private:

        // Window attributes
        CRect m_ControlRect;
        HGLRC hglrc;
        HDC hdc;

        // Layout
        _GraphLayout m_Layout;

        // Drawables
        _Border    m_Border;
        _Title     m_Title;
        _XAxis     m_XAxis;
        _YAxis     m_YAxis;
        _GraphArea m_GraphArea;

        // Graphs
        map<int, _GraphData> m_GraphData;
        int m_HandleCounter;

        // Min / Max
        double m_MaxAllGraphsX;
        double m_MaxAllGraphsY;
        double m_MinAllGraphsX;
        double m_MinAllGraphsY;
        double m_MaxX;
        double m_MaxY;
        double m_MinX;
        double m_MinY;

        // Zooming
        CPoint m_ZoomStartPoint;
        CPoint m_ZoomEndPoint;
        bool   m_ZoomActive;

        // Mouse cursor position
        CPoint m_CurrentCursorPosition;
        CPoint m_LastPoint;

        // Property dialog
        _GraphPropertyDialog m_PropertyDialog;

        // Selection
        _SelectionMarkerX m_SelectionMarkerLeft;
        _SelectionMarkerX m_SelectionMarkerRight;

        // Markers
        static _u32 MarkerHandle;
        map <_u32, _XMarker> m_XMarkers;
        map <_u32, _YMarker> m_YMarkers;

        // Background
    public:
        COLORREF m_BackgroundColor;


    private:
        void drawBackground();
        void drawSelectionMarkers();

    public:

        // Grid
        bool m_DrawGrid;

    public:

        void setRect(CRect Rect) {
            m_ControlRect = Rect;
            m_Layout.m_ControlRect = Rect;
        }

        // Methods
        virtual ~_GraphControl();
        map <_u32, _XMarker>& getXMarkers();
        map <_u32, _YMarker>& getYMarkers();
        void setBorder(_u32 Size, bool Visible, COLORREF Color);
        _FGHandle addGraph(TCHAR* Title);
        void addPoint(int Handle, double x, double y, bool UpdateBoundaries = true);
        void setMinMax(double X_Min, double X_Max, double Y_Min, double Y_Max);
        _FGHandle m_DialogHandle;
        void setDialogHandle(_FGHandle Handle) {
            m_DialogHandle = Handle;
            m_PropertyDialog.setGraphControlHandle(Handle);
        };
        void getMinMax(double* X_Min, double* X_Max, double* Y_Min, double* Y_Max);
        void setDefaultZoom();
        void  getLineColor(_FGHandle Handle, _u32* Color);
        void setLineColor(_FGHandle Handle, _u32 Color);
        void  getPointColor(_FGHandle Handle, _u32* Color);
        void setPointColor(_FGHandle Handle, _u32 Color);
        void  getVisible(_FGHandle Handle, bool* Visible);
        void getGraphVisible(_FGHandle Handle, bool* Visible);
        void setGraphVisible(_FGHandle Handle, bool Visible);
        _s32 calculateDefaultBoundaries();
        int addXMarker(double X, COLORREF Color, CString Comment = _T("___TICK_MARKER_TYPE"));
        int addYMarker(double Y, COLORREF Color, CString Comment = _T("___TICK_MARKER_TYPE"));
        void removeMarker(int Handle);
        void removeGraph(_FGHandle GraphHandle);
        void addSelectionMarker(double X);
        void calculateLayout();
        void initialiseOpenGl();
        int setPixelFormat(HDC hdc);
        _u32 getBorderSize();
        COLORREF getBorderColor();
        void setBorderSize(_u32 Size);
        void setBorderColor(COLORREF Color);
        void setBackgroundColor(COLORREF Color);
        void setAxisColor(COLORREF Color);
        COLORREF getAxisColor();

        // Axis modifiers
        void setXCaption(CString& Caption);
        void setYCaption(CString& Caption);
        CString& getXCaption();
        CString& getYCaption();


        // Mouse tracking
        bool getMouseTrackingEnabled();
        void setMouseTrackingEnabled(bool Enable);

        // Title
        CString& getTitle();
        void setTitle(CString& Title);

        // Generated message map functions
    protected:
        //{{AFX_MSG(_GraphControl)
        afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
        afx_msg void OnPaint();
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()

    public:
        // Message handler
        afx_msg void OnMouseMove(UINT nFlags, CPoint point);
        afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
        afx_msg BOOL OnEraseBkgnd(CDC* pDC);
        afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
        afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
        afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
        afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
        afx_msg void OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/);
        afx_msg void OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu);
        virtual BOOL OnCommand(WPARAM wParam, LPARAM lParam);
};
